package ch.janotta.slawo.da;

import java.util.HashMap;
import java.util.HashSet;

import ch.janotta.slawo.utilities.Dice;

public enum Background {
  Apostate(new People[] { People.ELF, People.HUMAN }, new CharacterClass[] { CharacterClass.MAGE }),
  Avvar(new People[] { People.HUMAN }, new CharacterClass[] { CharacterClass.ROGUE, CharacterClass.WARRIOR }),
  Circle_Mage(new People[] { People.ELF, People.HUMAN }, new CharacterClass[] { CharacterClass.MAGE }),
  City_Elf(new People[] { People.ELF }, new CharacterClass[] { CharacterClass.ROGUE, CharacterClass.WARRIOR }),
  Dalish_Elf(new People[] { People.ELF }, new CharacterClass[] { CharacterClass.ROGUE, CharacterClass.WARRIOR }),
  Fereldan_Freeman(new People[] { People.HUMAN }, new CharacterClass[] { CharacterClass.ROGUE, CharacterClass.WARRIOR }),
  Surface_Dwarf(new People[] { People.DWARF }, new CharacterClass[] { CharacterClass.ROGUE, CharacterClass.WARRIOR }),
  ;

  private static HashMap<CharacterClass, Background[]> possibleBackgrounds;
  static {
    possibleBackgrounds = new HashMap<>();
    possibleBackgrounds.put(CharacterClass.MAGE,
        new Background[] { Apostate, Circle_Mage });
    possibleBackgrounds.put(CharacterClass.ROGUE,
        new Background[] { Avvar, City_Elf, Dalish_Elf, Fereldan_Freeman, Surface_Dwarf });
    possibleBackgrounds.put(CharacterClass.WARRIOR,
        new Background[] { Avvar, City_Elf, Dalish_Elf, Fereldan_Freeman, Surface_Dwarf });
  }

  private HashSet<People> possiblePeople;
  private HashSet<CharacterClass> possibleClasses;

  private Background(People[] possiblePeople, CharacterClass[] possibleClasses) {
    this.possiblePeople = new HashSet<>();
    for (People people : possiblePeople) {
      this.possiblePeople.add(people);
    }
    this.possibleClasses = new HashSet<>();
    for (CharacterClass characterClass : possibleClasses) {
      this.possibleClasses.add(characterClass);
    }
  }

  public static Background getRandomInstance() {
    return getRandomElement(Background.values());
  }

  public static Background getBestRandomInstanceForAbility(Ability ability) {
    if (ability == Ability.Cunning || ability == Ability.Magic || ability == Ability.Willpower) {
      return getRandomElement(new Background[] { Background.Apostate, Background.Circle_Mage });
    } else {
      return getRandomElement(new Background[] {
          Background.Avvar,
          Background.City_Elf,
          Background.Dalish_Elf,
          Background.Fereldan_Freeman,
          Background.Surface_Dwarf
       });
    }
  }

  public static Background[] getPossibleBackgroundsForCharacterClass(CharacterClass characterClass) {
    return possibleBackgrounds.get(characterClass);
  }

  public People[] getPossiblePeople() {
    return this.possiblePeople.toArray(new People[0]);
  }

  public boolean canBeFromPeople(People people) {
    return this.possiblePeople.contains(people);
  }

  public CharacterClass[] getPossibleClasses() {
    return this.possibleClasses.toArray(new CharacterClass[0]);
  }

  public boolean canHaveClass(CharacterClass characterClass) {
    return this.possibleClasses.contains(characterClass);
  }

  private static Background getRandomElement(Background[] array) {
    int lastPossibleBackground = array.length;
    int randomBackgroundIndex = Dice.getRandomNumber(lastPossibleBackground) - 1;
    return array[randomBackgroundIndex];
  }
}
